﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Management;
using Microsoft.VisualBasic.Devices;

namespace PennApps
{
    public class ProcessPerformanceInformation
    {
        internal ProcessPerformanceInformation() { }
        public static ProcessPerformanceInformation[] CreateProcessPerforanceInformationArray()
        {
            ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_PerfFormattedData_PerfProc_Process");
            List<ProcessPerformanceInformation> perfList = new List<ProcessPerformanceInformation>();
            var allProcs = Process.GetProcesses();
            ComputerInfo computerInfo = new ComputerInfo();
            var totalMem = computerInfo.TotalPhysicalMemory;
            foreach (var obj in searcher.Get())
            {
                ProcessPerformanceInformation processPerfInfo = new ProcessPerformanceInformation();
                processPerfInfo.ProcessName = obj["Name"].ToString();
                var mem = Math.Ceiling((100 * (double.Parse(obj["WorkingSetPrivate"].ToString()) / (double)totalMem)));
                processPerfInfo.MemoryUsage = mem.ToString();
                if (mem > 100)
                {
                    throw new ApplicationException();
                }
                processPerfInfo.CPUUsage = obj["PercentProcessorTime"].ToString();
                processPerfInfo.TotalIOCount = ((UInt64)obj["IODataBytesPerSec"] + (UInt64)obj["IODataOperationsPerSec"] * 100).ToString();
                try
                {
                    processPerfInfo.ModuleLocation = allProcs.FirstOrDefault<Process>(proc => proc.Id.ToString() == obj["IDProcess"].ToString()).MainModule.FileName;
                }
                catch
                {
                    processPerfInfo.ModuleLocation = "";
                }
                perfList.Add(processPerfInfo);
            }
            var Total = perfList.Sum<ProcessPerformanceInformation>(new Func<ProcessPerformanceInformation, double>(o =>
                {
                    return double.Parse(o.TotalIOCount);
                }));
            foreach (var obj in perfList)
            {
                var orig = double.Parse(obj.TotalIOCount);
                obj.TotalIOCount = Math.Ceiling(((orig / Total) * 100)).ToString();
            }
            return perfList.ToArray();
        }
        public string ProcessName { get; set; }
        public string MemoryUsage { get; set; }
        public string CPUUsage { get; set; }
        public string TotalIOCount { get; set; }
        public string ModuleLocation { get; set; }

    }
}
